package com.kuangjia.student_ems.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kuangjia.student_ems.dto.LeaveDTO;
import com.kuangjia.student_ems.dto.UserDTO;
import com.kuangjia.student_ems.dto.request.LeaveRequest;
import com.kuangjia.student_ems.entity.Leave;
import com.kuangjia.student_ems.entity.User;
import com.kuangjia.student_ems.exception.BusinessException;
import com.kuangjia.student_ems.service.LeaveService;
import com.kuangjia.student_ems.service.UserService;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

@RestController
@RequestMapping("/leaves")
public class LeaveController {

    private static final Logger logger = LoggerFactory.getLogger(LeaveController.class);

    @Autowired
    private LeaveService leaveService;
    
    @Autowired
    private UserService userService;

    @PostMapping
    public ResponseEntity<LeaveDTO> applyLeave(@Valid @RequestBody LeaveRequest leaveRequest) {
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            String username = authentication.getName();
            UserDTO user = userService.getUserByUsername(username);
            return new ResponseEntity<>(leaveService.createLeave(user.getId(), leaveRequest), HttpStatus.CREATED);
        } catch (Exception e) {
            logger.error("申请请假时发生异常，请假类型: {}, 开始时间: {}", leaveRequest.getType(), leaveRequest.getStartTime(), e);
            throw e;
        }
    }

    @PutMapping("/{id}")
    public ResponseEntity<LeaveDTO> updateLeave(@PathVariable Long id, @Valid @RequestBody LeaveRequest leaveRequest) {
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            String username = authentication.getName();
            UserDTO currentUser = userService.getUserByUsername(username);
            
            // 获取当前请假记录
            LeaveDTO leaveDTO = leaveService.getLeaveById(id);
            
            // 检查权限：HR可以修改任何记录，普通用户只能修改自己的待审批记录
            boolean isHR = authentication.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_HR_ADMIN"));
            boolean isDepartmentManager = authentication.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_DEPARTMENT_MANAGER"));
            
            if (!isHR && !isDepartmentManager) {
                // 普通用户只能修改自己的记录
                if (!leaveDTO.getUserId().equals(currentUser.getId())) {
                    throw new BusinessException("您无权修改他人的请假记录");
                }
                
                // 普通用户只能修改待审批状态的记录
                if (leaveDTO.getStatus() != Leave.LeaveStatus.PENDING) {
                    throw new BusinessException("只能修改待审批状态的请假记录");
                }
            }
            
            return ResponseEntity.ok(leaveService.updateLeave(id, leaveRequest));
        } catch (Exception e) {
            logger.error("更新请假记录时发生异常，请假ID: {}, 请假类型: {}", id, leaveRequest.getType(), e);
            throw e;
        }
    }

    @GetMapping("/my")
    public ResponseEntity<List<LeaveDTO>> getMyLeaves() {
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            String username = authentication.getName();
            UserDTO user = userService.getUserByUsername(username);
            return ResponseEntity.ok(leaveService.getLeavesByUser(user.getId()));
        } catch (Exception e) {
            logger.error("获取我的请假记录时发生异常", e);
            throw e;
        }
    }

    @GetMapping("/pending")
    @PreAuthorize("hasAnyRole('HR_ADMIN', 'DEPARTMENT_MANAGER')")
    public ResponseEntity<List<LeaveDTO>> getPendingLeaves(@RequestParam(required = false) Long departmentId) {
        try {
            if (departmentId != null) {
                return ResponseEntity.ok(leaveService.getPendingLeavesByDepartment(departmentId));
            } else {
                return ResponseEntity.ok(leaveService.getLeavesByDepartmentAndStatus(null, Leave.LeaveStatus.PENDING));
            }
        } catch (Exception e) {
            logger.error("获取待审批请假记录时发生异常，部门ID: {}", departmentId, e);
            throw e;
        }
    }

    @GetMapping("/department/{departmentId}")
    @PreAuthorize("hasAnyRole('HR_ADMIN', 'DEPARTMENT_MANAGER')")
    public ResponseEntity<List<LeaveDTO>> getDepartmentLeaves(@PathVariable Long departmentId) {
        try {
            return ResponseEntity.ok(leaveService.getLeavesByDepartment(departmentId));
        } catch (Exception e) {
            logger.error("获取部门请假记录时发生异常，部门ID: {}", departmentId, e);
            throw e;
        }
    }

    @GetMapping("/user/{userId}")
    @PreAuthorize("hasAnyRole('HR_ADMIN', 'DEPARTMENT_MANAGER')")
    public ResponseEntity<List<LeaveDTO>> getUserLeaves(@PathVariable Long userId) {
        try {
            return ResponseEntity.ok(leaveService.getLeavesByUser(userId));
        } catch (Exception e) {
            logger.error("获取用户请假记录时发生异常，用户ID: {}", userId, e);
            throw e;
        }
    }

    @PutMapping("/{id}/approve")
    @PreAuthorize("hasAnyRole('HR_ADMIN', 'DEPARTMENT_MANAGER')")
    public ResponseEntity<LeaveDTO> approveLeave(
            @PathVariable Long id,
            @RequestParam(required = false) String approveReason) {
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            String username = authentication.getName();
            UserDTO approver = userService.getUserByUsername(username);
            return ResponseEntity.ok(leaveService.approveLeave(id, approver.getId(), approveReason));
        } catch (Exception e) {
            logger.error("审批请假时发生异常，请假ID: {}, 批准意见: {}", id, approveReason, e);
            throw e;
        }
    }

    @PutMapping("/{id}/reject")
    @PreAuthorize("hasAnyRole('HR_ADMIN', 'DEPARTMENT_MANAGER')")
    public ResponseEntity<LeaveDTO> rejectLeave(
            @PathVariable Long id,
            @RequestParam String rejectReason) {
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            String username = authentication.getName();
            UserDTO approver = userService.getUserByUsername(username);
            return ResponseEntity.ok(leaveService.rejectLeave(id, approver.getId(), rejectReason));
        } catch (Exception e) {
            logger.error("拒绝请假时发生异常，请假ID: {}, 拒绝原因: {}", id, rejectReason, e);
            throw e;
        }
    }

    @PutMapping("/{id}/cancel")
    public ResponseEntity<LeaveDTO> cancelLeave(@PathVariable Long id) {
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            String username = authentication.getName();
            UserDTO user = userService.getUserByUsername(username);
            // 这里我们假设需要验证用户是否是请假申请人
            return ResponseEntity.ok(leaveService.cancelLeave(id));
        } catch (Exception e) {
            logger.error("取消请假时发生异常，请假ID: {}", id, e);
            throw e;
        }
    }

    @GetMapping
    @PreAuthorize("hasAnyRole('HR_ADMIN', 'DEPARTMENT_MANAGER')")
    public ResponseEntity<List<LeaveDTO>> getAllLeaves() {
        try {
            return ResponseEntity.ok(leaveService.getAllLeaves());
        } catch (Exception e) {
            logger.error("获取所有请假记录时发生异常", e);
            throw e;
        }
    }

    @GetMapping("/search")
    @PreAuthorize("hasAnyRole('HR_ADMIN', 'DEPARTMENT_MANAGER')")
    public ResponseEntity<List<LeaveDTO>> searchLeaves(@RequestParam String keyword) {
        try {
            return ResponseEntity.ok(leaveService.searchLeaves(keyword));
        } catch (Exception e) {
            logger.error("搜索请假记录时发生异常，关键词: {}", keyword, e);
            throw e;
        }
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteLeave(@PathVariable Long id) {
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            String username = authentication.getName();
            UserDTO currentUser = userService.getUserByUsername(username);
            
            // 获取当前请假记录
            LeaveDTO leaveDTO = leaveService.getLeaveById(id);
            
            // 检查权限：HR可以删除任何记录，普通用户只能删除自己的记录
            boolean isHR = authentication.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_HR_ADMIN"));
            boolean isDepartmentManager = authentication.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_DEPARTMENT_MANAGER"));
            
            if (!isHR && !isDepartmentManager) {
                // 普通用户只能删除自己的记录
                if (!leaveDTO.getUserId().equals(currentUser.getId())) {
                    throw new BusinessException("您无权删除他人的请假记录");
                }
                
                // 移除状态限制，允许删除所有状态的请假记录
                // if (leaveDTO.getStatus() != Leave.LeaveStatus.PENDING) {
                //     throw new BusinessException("只能删除待审批状态的请假记录");
                // }
            }
            
            leaveService.deleteLeave(id);
            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
        } catch (Exception e) {
            logger.error("删除请假记录时发生异常，请假ID: {}", id, e);
            throw e;
        }
    }

    @GetMapping("/page")
    @PreAuthorize("hasAnyRole('HR_ADMIN', 'DEPARTMENT_MANAGER')")
    public IPage<LeaveDTO> getLeavePage(
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(defaultValue = "10") int pageSize,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) Long userId,
            @RequestParam(required = false, defaultValue = "createTime") String sortField,
            @RequestParam(required = false, defaultValue = "desc") String sortOrder) {
        try {
            if (pageNum < 1) pageNum = 1;
            if (pageSize < 1) pageSize = 10;
            Page<Leave> page = new Page<>(pageNum, pageSize);
            return leaveService.getLeavePage(page, keyword, userId, sortField, sortOrder);
        } catch (Exception e) {
            logger.error("分页查询请假记录时发生异常，页码: {}, 页大小: {}, 关键词: {}, 用户ID: {}", pageNum, pageSize, keyword, userId, e);
            // 返回空分页对象
            Page<LeaveDTO> emptyPage = new Page<>();
            emptyPage.setRecords(java.util.Collections.emptyList());
            emptyPage.setTotal(0);
            return emptyPage;
        }
    }
} 